﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.IO;
using ServBus.ListForm2010.Utility;
using System.Collections.Generic;
using ServBus.ListForm2010.Common.XSNOperator;
using ServBus.ListForm2010.License;

namespace ServBus.ListForm2010.Layouts.ListForm2010
{
    public partial class ListFormCustomize : LayoutsPageBase
    {
        private string _cTypeResrouceFolder;
        private string _errorMsg = "";

        private void errorLog(Exception ex, bool internalError)
        {
            if (internalError)
            {
                errorPanel.Visible = true;
            }
            else
            {
                LTException.Text = ex.Message;
                LTException.Visible = true;
            }
            ErrorLog.Write("ListFormCustomize" + "\r\n" + Request.Url + "\r\n" + ex.Message + "\r\n" + ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
        }

        #region Page Method

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                Activations activations = new Activations(SPContext.Current.Site.WebApplication);
                if (!activations.IsActivationValid(SPContext.Current.Web, out _errorMsg))
                {
                    errorLog(new Exception(_errorMsg), false);
                }
                else
                {
                    string xsnLocation = "";
                    string destFolderUrl;
                    Guid siteId = SPContext.Current.Site.ID;
                    //string _siteUrl = SPContext.Current.Site.Url;
                    Guid webId = SPContext.Current.Web.ID;
                    string listIdString = Page.Request["ListId"];
                    Guid listId = new Guid(listIdString);

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                web.AllowUnsafeUpdates = true;
                                SPList list = web.Lists[listId];
                                SPContentType cType = list.ContentTypes[0];
                                xsnLocation = web.Url + "/" + cType.ResourceFolder.Url + "/template.xsn";

                                if (!web.GetFile(xsnLocation).Exists)
                                {
                                    //display_lb.aspx, edit_lb.aspx, new_lb.aspx
                                    destFolderUrl = cType.ResourceFolder.ServerRelativeUrl;
                                    string listParameter = "listId=" + list.ID.ToString();
                                    string cTypeParameter = "ctypeId=" + cType.Id.ToString();
                                    string uploadFileName = Microsoft.SharePoint.Utilities.SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\ListForm2010\Template.aspx");
                                    FileStream fileStream = File.Open(uploadFileName, FileMode.Open);
                                    web.Files.Add(destFolderUrl + "/display_lb.aspx", fileStream, true);
                                    cType.DisplayFormUrl = destFolderUrl + "/display_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                    web.Files.Add(destFolderUrl + "/edit_lb.aspx", fileStream, true);
                                    cType.EditFormUrl = destFolderUrl + "/edit_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                    web.Files.Add(destFolderUrl + "/new_lb.aspx", fileStream, true);
                                    cType.NewFormUrl = destFolderUrl + "/new_lb.aspx?" + listParameter + "%26" + cTypeParameter;

                                    RegisterEventReceiver(list);

                                    fileStream.Close();
                                    cType.Update();
                                    list.Update();

                                    _cTypeResrouceFolder = cType.ResourceFolder.Name;

                                    #region Generate XSN
                                    //Create Main ListInfo
                                    //Main List
                                    XListInfo mListInfo = new XListInfo();
                                    mListInfo.GenerateListInfo(list);
                                    mListInfo.AddContentTypeInfo(cType);

                                    XSNOperator xsnOperator = new XSNOperator
                                    {
                                        SiteId = siteId,
                                        WebId = webId,
                                        ListId = list.ID,
                                        CTypeId = cType.Id,
                                        XSNTemplateFolder = Server.MapPath("/_layouts/ListForm2010/xsn_template/"),
                                        G_Site_Url = site.Url,
                                        G_XSN_Url =
                                            site.Url + list.RootFolder.ServerRelativeUrl + "/" +
                                            cType.ResourceFolder.Name + "/template.xsn",
                                        MListInfo = mListInfo
                                    };

                                    xsnOperator.GenerateXSN();
                                    UploadFileToFormLib(xsnOperator);
                                    #endregion
                                }
                            }
                        }
                    });

                    Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate('" + xsnLocation + "'); }window.close();</script>");
                }
            }
            catch (Exception ex)
            {
                errorLog(ex, true);
            }
        }

        #endregion


        #region GenerateXSN

        private void UploadFileToFormLib(XSNOperator p_XSNOperator)
        {
            try
            {
                System.Threading.Thread.Sleep(1000);
                // SPUtility.CreateFolderUnderList(mWeb,mList.Title,"defaultInfoPath");
                string xsnPath = p_XSNOperator.SaveFolder + "\\template\\template.xsn";
                SPSite site = new SPSite(p_XSNOperator.SiteId);
                SPWeb web = site.AllWebs[p_XSNOperator.WebId];
                SPList mlist = web.Lists[p_XSNOperator.ListId];
                SPUtility.CreateFile(site, web, mlist, _cTypeResrouceFolder, "template.xsn", GetXsnFileStream(xsnPath));
            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        private byte[] GetXsnFileStream(string xsnPath)
        {
            byte[] buf = new byte[100];
            List<byte> bytes = new List<byte>();
            using (FileStream fs = File.Open(xsnPath, FileMode.Open, FileAccess.Read))
            {
                const int offset = 0;
                while ((fs.Read(buf, offset, buf.Length)) > 0)
                {
                    CopyOneStreamToStream(buf, bytes);
                    buf = new byte[100];
                }
            }

            return bytes.ToArray();
        }

        private void CopyOneStreamToStream(IEnumerable<byte> byte1, ICollection<byte> byte2)
        {
            foreach (byte bt in byte1)
            {
                byte2.Add(bt);
            }
        }

        #endregion

        #region RegisterEventReceiver

        private static void RegisterEventReceiver(SPList list)
        {
            SPEventReceiverDefinition def1 = list.EventReceivers.Add();
            def1.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def1.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def1.Type = SPEventReceiverType.FieldAdded;
            def1.Name = "SPFieldChangeEventFieldAdded";
            def1.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def1.SequenceNumber = 1000;
            def1.Update();

            SPEventReceiverDefinition def2 = list.EventReceivers.Add();
            def2.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def2.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def2.Type = SPEventReceiverType.FieldUpdated;
            def2.Name = "SPFieldChangeEventFieldUpdated";
            def2.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def2.SequenceNumber = 1000;
            def2.Update();

            SPEventReceiverDefinition def3 = list.EventReceivers.Add();
            def3.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def3.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def3.Type = SPEventReceiverType.FieldDeleting;
            def3.Name = "SPFieldChangeEventFieldDeleting";
            def3.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def3.SequenceNumber = 1000;
            def3.Update();
        }

        #endregion

    }
}
